<template>
  <FormItem
    v-bind="formItemProps"
    :class="[
      'form-checkbox-group',
      { 'form-checkbox-group-row': fillRow },
      ellipsis ? 'form-checkbox-group-row-ellipsis' : fillRow ? 'form-checkbox-group-row-break-word' : ''
    ]"
    :rules="computeRules"
    :disabled="inputDisabled">
    <template #default>
      <ElCheckboxGroup
        :disabled="inputDisabled"
        :value="computeVal"
        :placeholder="computePlaceholder"
        v-bind="inputProps"
        v-on="listeners"
        @input="emitInput">
        <ElCheckbox v-for="item in innerOptions" :key="item[valueKey]" :label="item[valueKey]">
          {{ item[labelKey] }}
        </ElCheckbox>
      </ElCheckboxGroup>
      <FormInput
        v-if="computeVal.includes(otherVal)"
        :wrap-col="false"
        class="form-checkbox-group-other"
        label-width="0"
        :prop="otherProp"
        :disabled="inputDisabled"
        :required="!!otherProp"
        :placeholder="otherPlaceholder"
        :label="otherLabel"
        :show-message="!!otherLabel"
        :style="!otherLabel ? { marginBottom: 0, width: otherWidth } : { width: otherWidth }"
        :value="other"
        :max-length="otherMaxLength"
        @input="val => $emit('update:other', val)" />
    </template>
    <template #error="{ error }">
      <slot name="error" :error="error"></slot>
    </template>
    <template #label>
      <slot name="label"></slot>
    </template>
    <template #below>
      <slot name="below"></slot>
    </template>
  </FormItem>
</template>

<script>
  import formInput from './form-input'
  import formPick from '@/components/form/form-pick'
  import { filterProperties, normalizeProps } from '@/util'
  import { CheckboxGroup } from 'element-ui'

  const autoBindKeys = Object.keys(CheckboxGroup.props).filter(
    key => !['value', 'placeholder', 'disabled'].includes(key)
  )

  export default {
    name: 'FormCheckboxGroup',
    mixins: [formInput, formPick],
    props: {
      options: {
        type: Array,
        default: () => []
      },
      value: [String, Array],
      other: [String],
      otherVal: [String],
      otherProp: String,
      otherPlaceholder: String,
      otherLabel: String,
      otherWidth: {
        type: String,
        default: '200px'
      },
      otherMaxLength: String,
      gender: Boolean,
      confirm: Boolean,
      labelProp: {
        type: String,
        default: 'name'
      },
      valueProp: {
        type: String,
        default: 'code'
      },
      split: Boolean,
      sort: Boolean,
      classic: Boolean,
      fillRow: Boolean,
      ellipsis: Boolean
    },
    computed: {
      prefix() {
        return '请选择'
      },
      labelKey() {
        return this.classic ? 'label' : this.labelProp
      },
      valueKey() {
        return this.classic ? 'value' : this.valueProp
      },
      inputProps() {
        return filterProperties({ ...normalizeProps(this.$attrs), ...this.$props }, autoBindKeys)
      },
      innerOptions() {
        if (this.gender) {
          return [
            {
              [this.labelKey]: '男',
              [this.valueKey]: '男'
            },
            {
              [this.labelKey]: '女',
              [this.valueKey]: '女'
            }
          ]
        }
        if (this.confirm) {
          return [
            {
              [this.labelKey]: '是',
              [this.valueKey]: '是'
            },
            {
              [this.labelKey]: '否',
              [this.valueKey]: '否'
            }
          ]
        }
        return this.options
      },
      computeVal() {
        if (this.split) {
          if (this.value) {
            return this.value.split(',')
          } else {
            return []
          }
        } else {
          return this.value || []
        }
      }
    },
    methods: {
      emitInput(val) {
        if (this.split) {
          if (this.sort) {
            this.$emit('input', val.sort().join(','))
          } else {
            this.$emit('input', val.join(','))
          }
        } else {
          if (this.sort) {
            this.$emit('input', val.sort())
          } else {
            this.$emit('input', val)
          }
        }
      }
    }
  }
</script>

<style lang="scss">
  .form-checkbox-group {
    &.form-checkbox-group-row {
      &.form-checkbox-group-row-ellipsis {
        .el-checkbox__label {
          @include ellipsis-line;
        }
      }

      &.form-checkbox-group-row-break-word {
        .el-checkbox__label {
          @include break-word;
        }
      }

      .el-checkbox-group {
        display: block;
      }

      .el-checkbox {
        @include flex-row;
        flex-wrap: nowrap;
        width: 100%;
      }

      .el-checkbox__input {
        @include flex-not-shrink;
        top: 3px;
      }

      .el-checkbox__label {
        @include flex-item;
        display: block;
        margin-bottom: 6px;
        vertical-align: sub;
      }
    }

    .form-checkbox-group-other {
      display: inline-block;
      margin-left: 10px;

      .el-form-item__label {
        display: none;
      }
    }

    .el-checkbox-group {
      line-height: inherit;
    }

    .el-checkbox {
      margin-right: 10px;
      vertical-align: middle;
    }

    .el-checkbox__label {
      padding-left: 4px;
    }
  }
</style>
